﻿using System;
using System.Linq;
using System.Reflection;
using System.Web.Mvc;
using AutoMapper;
using Mehdime.Entity;
using SimpleInjector;
using SimpleInjector.Advanced;
using SimpleInjector.Integration.Web;
using SimpleInjector.Integration.Web.Mvc;
using WebGrease.Css.Extensions;
using WikeSoft.Data;
using WikeSoft.Enterprise;
using WikeSoft.WorkFlowEngine.AppServices;
using WikeSoft.WorkFlowEngine.Interfaces;

namespace WikeSoft.Web
{
    /// <summary>
    /// ioc配置
    /// </summary>
    public class IocConfig
    {

        private static Container _container;

        
        /// <summary>
        /// 注册
        /// </summary>
        public static void Register()
        {
            RegisterForMvc();
        }

        /// <summary>
        /// RegisterForMvc
        /// </summary>
        private static Container RegisterForMvc()
        {
            if (_container == null)
            {
                _container = new Container();
                _container.Options.ConstructorResolutionBehavior = new LessConstructorBehavior();
                _container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();

                // Register your types, for instance:
                RegisterForWebApiProxyClient(_container);

                // This is an extension method from the integration package.
                _container.RegisterMvcControllers(Assembly.GetExecutingAssembly());

                // This is an extension method from the integration package as well.
                _container.RegisterMvcIntegratedFilterProvider();

                _container.Verify();

                DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(_container));
            }
           

            return _container;
        }

        /// <summary>
        /// RegisterForWebApiProxyClient
        /// </summary>
        /// <param name="container"></param>
        private static void RegisterForWebApiProxyClient(Container container)
        {
            //dbcontext
            container.Register<IDbContextScopeFactory>(() => new DbContextScopeFactory(), Lifestyle.Scoped);

            container.Register<IWorkFlowDesignService>(() => new WorkFlowDesignService(), Lifestyle.Scoped);
            container.Register<IWorkFlowInstanceService>(() => new WorkFlowInstanceService(), Lifestyle.Scoped);
            container.Register<IWorkFlowCategoryService>(() => new WorkFlowCategoryService(), Lifestyle.Scoped);

            //service
            var moduleInitializers = new ModuleInitializer[]
            {
                new WikeModuleInitializer()
            };

            moduleInitializers.ForEach(x => x.LoadIoc(container));

            //automapper
            container.Register<IConfigurationProvider>(AutoMapperConfig.GetMapperConfiguration, Lifestyle.Singleton);
            container.Register(() => AutoMapperConfig.GetMapperConfiguration().CreateMapper(), Lifestyle.Scoped);
        }
    }

    /// <summary>
    /// 多个构造函数的情况，指定DI容器，寻找参数最少的构造函数
    /// </summary>
    public class LessConstructorBehavior : IConstructorResolutionBehavior
    {
        /// <summary>
        /// 获取构造函数
        /// </summary>
        /// <param name="serviceType"></param>
        /// <param name="implementationType"></param>
        /// <returns></returns>
        public ConstructorInfo GetConstructor(Type serviceType, Type implementationType)
        {
            return implementationType.GetConstructors().OrderBy(x => x.GetParameters().Length).FirstOrDefault();
        }
    }
}